package com.example.demo.controller;


import com.example.demo.datasource.DynamicDataSource;
import com.example.demo.model.CustomResult;
import com.example.demo.model.TenantInfo;
import com.example.demo.service.ITenantInfoService;
import com.example.demo.utils.CustomUtil;
import com.example.demo.utils.DateUtil;
import com.example.demo.utils.ResultEnum;
import com.example.demo.utils.SpringContextUtils;
import com.zaxxer.hikari.HikariDataSource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author Lij
 * @since 2020-05-19
 */
@Slf4j
@RestController
@RequestMapping("/tenantInfo")
public class TenantInfoController {

    @Autowired
    private ITenantInfoService tenantInfoService;

    @GetMapping("/info")
    public CustomResult<TenantInfo> getInfo() {
        List<TenantInfo> list = tenantInfoService.list();
        return CustomResult.Ok(list);
    }

    @GetMapping("/save")
    public CustomResult<?> saveInfo() throws Exception {
        TenantInfo tenantInfo = new TenantInfo();
        tenantInfo.setId(UUID.randomUUID().toString());
        tenantInfo.setTenantId(CustomUtil.GenerateID());
        tenantInfo.setTenantName("动态新增");
        tenantInfo.setDatasourceUrl("jdbc:mysql://192.168.99.100:3306/" + "hd_" + tenantInfo.getTenantId() + "?createDatabaseIfNotExist=true&useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=GMT%2B8");
        tenantInfo.setDatasourceUsername("test");
        tenantInfo.setDatasourcePassword("test123");
        tenantInfo.setDatasourceDriver("com.mysql.cj.jdbc.Driver");
        tenantInfo.setStatus(true);
        tenantInfo.setSystemAccount("test");
        tenantInfo.setSystemPassword("test123");
        tenantInfo.setSystemProject("hd_" + tenantInfo.getTenantId());
        tenantInfo.setCreateTime(DateUtil.getCurrent());
        tenantInfo.setUpdateTime(DateUtil.getCurrent());
        boolean b = tenantInfoService.save(tenantInfo);
        if (b) {
            //创建数据库，加载数据源
            initDataBase(tenantInfo.getSystemProject());
            log.info("======初始化动态数据源=====");
            DynamicDataSource dynamicDataSource = (DynamicDataSource) SpringContextUtils.getBean("dynamicDataSource");

            HikariDataSource master = (HikariDataSource) SpringContextUtils.getBean("master");
            Map<Object, Object> dataSourceMap = new HashMap<>();
            dataSourceMap.put("master", master);

            TenantInfo tenantInfos = tenantInfoService.getById(tenantInfo.getId());
            log.info(tenantInfos.getTenantId() + "     " + tenantInfos.getTenantName());
            HikariDataSource dataSource = new HikariDataSource();
            dataSource.setDriverClassName(tenantInfos.getDatasourceDriver());
            dataSource.setJdbcUrl(tenantInfos.getDatasourceUrl());
            dataSource.setUsername(tenantInfos.getDatasourceUsername());
            dataSource.setPassword(tenantInfos.getDatasourcePassword());
            dataSource.setDataSourceProperties(master.getDataSourceProperties());
            dataSourceMap.put(tenantInfos.getTenantId(), dataSource);
            // 设置数据源
            dynamicDataSource.setDataSources(dataSourceMap);
            /**
             * 必须执行此操作，才会重新初始化AbstractRoutingDataSource 中的 resolvedDataSources，也只有这样，动态切换才会起效
             */
            dynamicDataSource.afterPropertiesSet();
        }
        return CustomResult.Build(b, b ? ResultEnum.Success.getIndex() : ResultEnum.Fail.getIndex());
    }

    public boolean initDataBase(String dataBaseName) throws Exception {
        //加载注册
        Class.forName("com.mysql.cj.jdbc.Driver");
//一开始必须填一个已经存在的数据库
        String url = "jdbc:mysql://192.168.99.100:3306/mysql?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT";
        //建立连接
        Connection conn = DriverManager.getConnection(url, "root", "801801ls");
        Statement stat = conn.createStatement();
        //判断数据库是否存在
        String checkdatabase = "show databases like \"" + dataBaseName + "\"";
        //创建数据库
        String createdatabase = "create  database  " + dataBaseName + ";";
        stat = (Statement) conn.createStatement();
        ResultSet resultSet = stat.executeQuery(checkdatabase);
        //若数据库存在
        if (resultSet.next()) {
            System.out.println("" + dataBaseName + " exist!");
            stat.close();
            conn.close();
        } else {
            if (stat.executeUpdate(createdatabase) == 0) {

            }
            //若数据库不存在
//打开创建的数据库
            url = new String();
            url = "jdbc:mysql://192.168.99.100:3306/" + dataBaseName + "?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT";
            conn = DriverManager.getConnection(url, "root", "801801ls");
            stat = conn.createStatement();

//创建表 angle_difference
            stat.executeUpdate("DROP TABLE IF EXISTS `t_user`");
            stat.executeUpdate("create table t_user\n" +
                    "(\n" +
                    "  id               varchar(64) not null\n" +
                    "  comment '主键'\n" +
                    "    primary key,\n" +
                    "  user_name        varchar(64) null\n" +
                    "  comment '主键',\n" +
                    "  password         varchar(64) null\n" +
                    "  comment '主键',\n" +
                    "  real_name        varchar(64) null\n" +
                    "  comment '主键',\n" +
                    "  id_card          varchar(64) null\n" +
                    "  comment '主键',\n" +
                    "  e_mail           varchar(64) null\n" +
                    "  comment '主键',\n" +
                    "  tel_phone        varchar(64) null\n" +
                    "  comment '主键',\n" +
                    "  entry_time       varchar(64) null\n" +
                    "  comment '主键',\n" +
                    "  resignation_time varchar(64) null\n" +
                    "  comment '主键',\n" +
                    "  position_id      varchar(64) null\n" +
                    "  comment '主键',\n" +
                    "  sex              int         null\n" +
                    "  comment '主键',\n" +
                    "  birthday         varchar(64) null\n" +
                    "  comment '主键',\n" +
                    "  operator         varchar(64) null\n" +
                    "  comment '主键',\n" +
                    "  dept_id          varchar(64) null\n" +
                    "  comment '主键',\n" +
                    "  login_time       varchar(64) null\n" +
                    "  comment '主键',\n" +
                    "  expire_time      varchar(64) null\n" +
                    "  comment '主键',\n" +
                    "  expire_status    int         null\n" +
                    "  comment '主键',\n" +
                    "  status           int         null\n" +
                    "  comment '主键',\n" +
                    "  is_admin         int         null\n" +
                    "  comment '主键',\n" +
                    "  create_time      varchar(64) null\n" +
                    "  comment '主键',\n" +
                    "  update_time      varchar(64) null\n" +
                    "  comment '主键'\n" +
                    ");\n" +
                    "\n");
            stat.executeUpdate("INSERT INTO t_user (id, user_name, password, real_name, id_card, e_mail, tel_phone, entry_time, resignation_time, position_id, sex, birthday, operator, dept_id, login_time, expire_time, expire_status, status, is_admin, create_time, update_time) VALUES ('1', '张三', '1', '张二愣子', null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null);");
            stat.close();
            conn.close();
            System.out.println("create table success!");

        }
        return true;
    }

}
